package com.ruicar.afs.cloud.apply.pre.loan.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.apply.common.entity.*;
import com.ruicar.afs.cloud.apply.common.utils.ApplyConstants;
import com.ruicar.afs.cloud.apply.contract.enums.CertTypePictureEnum;
import com.ruicar.afs.cloud.apply.contract.enums.IsMainEnum;
import com.ruicar.afs.cloud.apply.contract.enums.UploadIDImageSceneEnum;
import com.ruicar.afs.cloud.apply.contract.vo.ApplyLoanAmtVo;
import com.ruicar.afs.cloud.apply.contract.vo.ContractFileVo;
import com.ruicar.afs.cloud.apply.pre.approve.service.PreApproveService;
import com.ruicar.afs.cloud.apply.pre.loan.condition.CustInfoCondition;
import com.ruicar.afs.cloud.apply.pre.loan.mapper.ApplyCustBaseInfoMapper;
import com.ruicar.afs.cloud.apply.pre.loan.service.*;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.modules.apply.dto.ApplyIdCardDTO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author: Lee
 * @date: 2020/5/13 21:19
 * @description:客户主表信息service实现类
 */
@Service
@Slf4j
@AllArgsConstructor
public class ApplyCustBaseInfoServiceImpl extends ServiceImpl<ApplyCustBaseInfoMapper, ApplyCustBaseInfo> implements ApplyCustBaseInfoService {

    private final PreApproveService preApproveService;
    private final ApplyCustPersonalService applyCustPersonalService;
    private final ApplyCustAddressService applyCustAddressService;
    private final ApplyOrderInfoService applyOrderInfoService;
    private final ApplyCustContactsService applyCustContactsService;

    /**
     * 获取客户主表信息
     *
     * @param condition
     * @return
     */
    @Override
    public ApplyCustBaseInfo getCustBaseInfo(CustInfoCondition condition) {
        return null;
    }

    /**
     * 通过申请编号和证件编号查询
     *
     * @param applyNo
     * @param certNo
     * @return
     */
    public ApplyCustBaseInfo getCustInfoByCertNo(String applyNo, String certNo) {

        ApplyCustBaseInfo applyCustBaseInfo = this.baseMapper.selectOne(Wrappers.<ApplyCustBaseInfo>query().lambda().eq(ApplyCustBaseInfo::getApplyNo, applyNo).eq(ApplyCustBaseInfo::getCertNo, certNo));
        return applyCustBaseInfo;
    }

    /**
     * 通过申请编号获取客户列表
     *
     * @param applyNo
     * @return
     */
    @Override
    public List<ApplyCustBaseInfo> getCustBaseInfoList(String applyNo) {

        List<ApplyCustBaseInfo> list = this.baseMapper.selectList(Wrappers.<ApplyCustBaseInfo>query().lambda().eq(ApplyCustBaseInfo::getApplyNo, applyNo));
        return list;
    }

    /**
     * 通过申请编号和角色获取客户信息
     *
     * @param applyNo
     * @return
     */
    @Override
    public ApplyCustBaseInfo getCustBaseInfo(String applyNo, String custRole) {

        return this.baseMapper.selectOne(Wrappers.<ApplyCustBaseInfo>query().lambda().eq(ApplyCustBaseInfo::getApplyNo, applyNo).eq(ApplyCustBaseInfo::getCustRole, custRole));
    }


    /**
     * 保存/更新 客户基础信息-客户基础信息/户籍地址/身份证正反面/详细信息
     *
     * @param condition
     */
    @Override
    public void saveCustomerBaseInfo(CustInfoCondition condition) throws AfsBaseException {
        //客户基础信息
        ApplyCustBaseInfo applyCustBaseInfo = condition.getApplyCustBaseInfo();
        //获取客户明细
        ApplyCustPersonalDetail personalDetail = condition.getPersonalDetail();
        //获取户籍地址
        String[] permanentAdreess = personalDetail.getPermanentAdreess();
        if (ObjectUtil.isNotNull(applyCustBaseInfo)) {
            if (StringUtil.isEmpty(applyCustBaseInfo.getCertNo())) {
                throw new AfsBaseException("证件号不能为空");
            } else if (StringUtil.isEmpty(applyCustBaseInfo.getCustName())) {
                throw new AfsBaseException("客户姓名不能为空");
            }
        } else {
            throw new AfsBaseException("请先录入客户信息");
        }
        //插入之前，先根据角色，申请编号，查客户是否已经存在
        ApplyCustBaseInfo custBaseInfo = this.getCustBaseInfo(condition.getApplyNo(), condition.getCustRole());
        //插入之前，先根据证件号，申请编号，查客户是否已经存在，如果存在就抛错
        List<ApplyCustBaseInfo> list = this.list(Wrappers.<ApplyCustBaseInfo>query().lambda()
                .eq(StringUtil.isNotEmpty(condition.getApplyNo()), ApplyCustBaseInfo::getApplyNo, condition.getApplyNo()));
        if (CollectionUtil.isNotEmpty(list)) {
            for (ApplyCustBaseInfo baseInfo : list) {
                //如果和查詢出來的角色不相同
                if (!baseInfo.getCustRole().equals(condition.getCustRole())) {
                    //如果證件號相同
                    if (baseInfo.getCertNo().equals(applyCustBaseInfo.getCertNo())) {
                        throw new AfsBaseException("客户证件号不可重复");
                    }
                    //如果手機號相同
                    if (baseInfo.getTelPhone().equals(applyCustBaseInfo.getTelPhone())) {
                        throw new AfsBaseException("客户手机号不可重复");
                    }
                    //如果客户姓名相同
                    if (baseInfo.getCustName().equals(applyCustBaseInfo.getCustName())) {
                        throw new AfsBaseException("客户姓名不可重复");
                    }
                }
            }
        }
        //存在
        if (ObjectUtil.isNotNull(custBaseInfo)) {
            //同一角色
            if (custBaseInfo.getCustRole().equals(condition.getCustRole())) {
                if (!custBaseInfo.getCustName().equals(applyCustBaseInfo.getCustName())) {
                    //客户姓名更改-重出标识
                    applyCustBaseInfo.setReappearFlag(ApplyConstants.APP_FORM_STATE_ONE);
                } else if (!custBaseInfo.getCertNo().equals(applyCustBaseInfo.getCertNo())) {
                    //证件号码更改-重出标识
                    applyCustBaseInfo.setReappearFlag(ApplyConstants.APP_FORM_STATE_ONE);
                } else if (!custBaseInfo.getCertType().equals(applyCustBaseInfo.getCertType())) {
                    //证件类型更改-重出标识
                    applyCustBaseInfo.setReappearFlag(ApplyConstants.APP_FORM_STATE_ONE);
                } else if (!custBaseInfo.getTelPhone().equals(applyCustBaseInfo.getTelPhone())) {
                    //电话号码更改-重出标识
                    applyCustBaseInfo.setReappearFlag(ApplyConstants.APP_FORM_STATE_ONE);
                }
            }
            //将库内数据为前端输入的客户信息
            applyCustBaseInfo.setId(custBaseInfo.getId());
            this.updateById(applyCustBaseInfo);
            //更新订单主表内的客户姓名
            if (ApplyConstants.PRINCIPAL_BORROWER.equals(condition.getCustRole())) {
                ApplyOrderInfo orderInfoByApplyNo = applyOrderInfoService.getOrderInfoByApplyNo(applyCustBaseInfo.getApplyNo());
                orderInfoByApplyNo.setCustName(applyCustBaseInfo.getCustName());
                applyOrderInfoService.updateById(orderInfoByApplyNo);
            }
            this.preApproveService.storeCardImage(condition.getFrontIDCard(), condition.getReverseIDCard(), UploadIDImageSceneEnum.CUSTOMER_INFO_ID_CARD_IMAGE_SCENE.getCode(), condition.getCustRole(), condition.getApplyNo());
            //个人明细
            ApplyCustPersonalDetail custPersonalDetail = this.applyCustPersonalService.getCustPersonalDetail(condition.getApplyNo(), custBaseInfo.getId());
            if (ObjectUtil.isNotNull(personalDetail)) {
                //数据库已存在就更新
                if (ObjectUtil.isNotNull(custPersonalDetail)) {
                    personalDetail.setId(custPersonalDetail.getId());
                    this.applyCustPersonalService.updateById(personalDetail);
                } else {
                    //数据库不存在，就保存
                    personalDetail.setApplyNo(condition.getApplyNo());
                    personalDetail.setCustId(custBaseInfo.getId());
                    //保存户籍地址
                    ApplyCustAddressDetails applyCustAddressDetails = new ApplyCustAddressDetails();
                    applyCustAddressDetails.setApplyNo(custBaseInfo.getApplyNo());
                    applyCustAddressDetails.setCustId(custBaseInfo.getId());
                    //户籍地址设置有效性
                    applyCustAddressDetails.setIsMain(IsMainEnum.isMain.getCode());
                    applyCustAddressDetails.setDetailAddressTemp(permanentAdreess);
                    applyCustAddressDetails.setAddressType(ApplyConstants.PERMANENT_ADDRESS);
                    applyCustAddressDetails.setCreateBy(SecurityUtils.getUsername());
                    applyCustAddressDetails.setCreateTime(new Date());
                    applyCustAddressService.save(applyCustAddressDetails);
                    this.applyCustPersonalService.save(personalDetail);
                }
            }
            //先查询地址明细
            List<ApplyCustAddressDetails> detailsList = applyCustAddressService.list(Wrappers.<ApplyCustAddressDetails>query().lambda()
                    .eq(ApplyCustAddressDetails::getCustId, applyCustBaseInfo.getId()));
            if (CollectionUtil.isNotEmpty(detailsList)) {
                //遍历出地址id
                for (ApplyCustAddressDetails details : detailsList) {
                    //如果存在主借人户籍地址
                    if (ApplyConstants.ONE.equals(details.getIsMain())) {
                        details.setDetailAddressTemp(permanentAdreess);
                        //更新户籍地址
                        applyCustAddressService.updateById(details);
                    }
                }
            }
        } else {
            if (ApplyConstants.PRINCIPAL_BORROWER.equals(condition.getCustRole())) {
                applyCustBaseInfo.setCustRole(ApplyConstants.PRINCIPAL_BORROWER);
            } else if (ApplyConstants.COMMON_BORROWER.equals(condition.getCustRole())) {
                applyCustBaseInfo.setCustRole(ApplyConstants.COMMON_BORROWER);
            } else if (ApplyConstants.GUARANTOR.equals(condition.getCustRole())) {
                applyCustBaseInfo.setCustRole(ApplyConstants.GUARANTOR);
            }
            applyCustBaseInfo.setApplyNo(condition.getApplyNo());
            //不存在就新增
            this.baseMapper.insert(applyCustBaseInfo);
            this.preApproveService.storeCardImage(condition.getFrontIDCard(), condition.getReverseIDCard(), UploadIDImageSceneEnum.CUSTOMER_INFO_ID_CARD_IMAGE_SCENE.getCode(), condition.getCustRole(), condition.getApplyNo());
            //查询客户基础信息
            ApplyCustBaseInfo info = this.baseMapper.selectOne(Wrappers.<ApplyCustBaseInfo>query().lambda()
                    .eq(ApplyCustBaseInfo::getApplyNo, condition.getApplyNo())
                    .eq(ApplyCustBaseInfo::getCertNo, applyCustBaseInfo.getCertNo()));
            //个人明细
            if (ObjectUtil.isNotNull(personalDetail)) {
                //已存在就更新
                if (personalDetail.getId() != null) {
                    this.applyCustPersonalService.updateById(personalDetail);
                } else {
                    personalDetail.setApplyNo(condition.getApplyNo());
                    personalDetail.setCustId(info.getId());
                    this.applyCustPersonalService.save(personalDetail);
                }
            }
            //获取户籍地址
            ApplyCustAddressDetails applyCustAddressDetails = new ApplyCustAddressDetails();
            //保存基本信息内的户籍地址
            if (ArrayUtils.isNotEmpty(permanentAdreess)) {
                applyCustAddressDetails.setApplyNo(info.getApplyNo());
                applyCustAddressDetails.setCustId(info.getId());
                //户籍地址设置有效性
                applyCustAddressDetails.setIsMain(IsMainEnum.isMain.getCode());
                applyCustAddressDetails.setDetailAddressTemp(permanentAdreess);
                applyCustAddressDetails.setAddressType(ApplyConstants.PERMANENT_ADDRESS);
                applyCustAddressDetails.setCreateBy(SecurityUtils.getUsername());
                applyCustAddressDetails.setCreateTime(new Date());
                //保存户籍地址到地址明细表
                applyCustAddressService.save(applyCustAddressDetails);
            }
        }
    }

    /**
     * 保存/更新工作信息
     *
     * @param condition 工作信息
     */
    @Override
    public void saveWorkData(CustInfoCondition condition) {
        ApplyCustPersonalDetail personalDetail = condition.getPersonalDetail();
        if (ObjectUtil.isNotNull(personalDetail)) {
            //根据申请编号,角色,查询客户信息
            ApplyCustBaseInfo custBaseInfo = this.getCustBaseInfo(condition.getApplyNo(), condition.getCustRole());
            if (ObjectUtil.isNotNull(custBaseInfo)) {
                //根据申请编号查询客户明细
                ApplyCustPersonalDetail custPersonalDetail = this.applyCustPersonalService.getCustPersonalDetail(condition.getApplyNo(), custBaseInfo.getId());
                if (ObjectUtil.isNotNull(custPersonalDetail)) {
                    personalDetail.setId(custPersonalDetail.getId());
                    //更新个人明细
                    applyCustPersonalService.updateById(personalDetail);
                }
            }
        }
    }

    /**
     * 保存/更新地址信息
     *
     * @param condition 地址信息
     */
    @Override
    public void saveAddress(CustInfoCondition condition) {
        //查询客户信息
        ApplyCustBaseInfo custBaseInfo = this.getCustBaseInfo(condition.getApplyNo(), condition.getCustRole());
        List<ApplyCustAddressDetails> addressDetailsList = condition.getAddressDetailsList();
        if (CollectionUtil.isNotEmpty(addressDetailsList)) {
            addressDetailsList.forEach(applyCustAddressDetails -> {
                //地址信息id存在
                if (applyCustAddressDetails.getId() != null) {
                    //更新地址信息
                    applyCustAddressService.updateById(applyCustAddressDetails);
                } else {
                    applyCustAddressDetails.setApplyNo(condition.getApplyNo());
                    applyCustAddressDetails.setCustId(custBaseInfo.getId());
                    //不存在id，就保存
                    applyCustAddressService.save(applyCustAddressDetails);
                }
            });
        }
    }

    @Override
    public List<ApplyLoanAmtVo> getApplyLoanAmt(List certNo) {
        List<ApplyLoanAmtVo> applyLoanAmtVos = this.baseMapper.getApplyLoanAmt(certNo);
        return applyLoanAmtVos;
    }

    @Override
    public List<ApplyCustBaseInfo> getApplyPhone(ApplyIdCardDTO condition) {
        List<ApplyCustBaseInfo> custBaseInfoList = this.baseMapper.getApplyPhone(condition);
        return custBaseInfoList;
    }

    /**
     * 保存客户信息及证件照
     *
     * @param condition
     */
    @Override
    public List saveSignParams(CustInfoCondition condition) {
        List list = new ArrayList<>(5);
        Map<String, String> stringMap = new HashMap<>(5);
        Map<String, String> fileId;
        String fileName;
        List<ContractFileVo> contractFileVos = condition.getContractFileVos();
        if (CollectionUtil.isNotEmpty(contractFileVos)) {
            for (ContractFileVo contractFileVo : contractFileVos) {
                //主借人身份证正面
                if (CertTypePictureEnum.MAIN_BORROWER_ID_CARD_FRONT.getIndex().equals(contractFileVo.getType())) {
                    stringMap.put("md5", contractFileVo.getMd5());
                    fileName = contractFileVo.getType();
                    this.preApproveService.setImageStore(fileName, stringMap, condition.getApplyNo());
                } else if (CertTypePictureEnum.MAIN_BORROWER_ID_CARD_BACK.getIndex().equals(contractFileVo.getType())) {
                    //主借人身份证反面
                    stringMap.put("md5", contractFileVo.getMd5());
                    fileName = contractFileVo.getType();
                    this.preApproveService.setImageStore(fileName, stringMap, condition.getApplyNo());
                } else if (CertTypePictureEnum.COM_BORROWER_ID_CARD_FRONT.getIndex().equals(contractFileVo.getType())) {
                    //共借人正面
                    stringMap.put("md5", contractFileVo.getMd5());
                    fileName = contractFileVo.getType();
                    this.preApproveService.setImageStore(fileName, stringMap, condition.getApplyNo());
                } else if (CertTypePictureEnum.COM_BORROWER_ID_CARD_BACK.getIndex().equals(contractFileVo.getType())) {
                    //共借人反面
                    stringMap.put("md5", contractFileVo.getMd5());
                    fileName = contractFileVo.getType();
                    this.preApproveService.setImageStore(fileName, stringMap, condition.getApplyNo());
                } else if (CertTypePictureEnum.GUARANTOR_BORROWER_ID_CARD_FRONT.getIndex().equals(contractFileVo.getType())) {
                    //担保人正面
                    stringMap.put("md5", contractFileVo.getMd5());
                    fileName = contractFileVo.getType();
                    this.preApproveService.setImageStore(fileName, stringMap, condition.getApplyNo());
                } else if (CertTypePictureEnum.GUARANTOR_BORROWER_ID_CARD_BACK.getIndex().equals(contractFileVo.getType())) {
                    //担保人反面
                    stringMap.put("md5", contractFileVo.getMd5());
                    fileName = contractFileVo.getType();
                    this.preApproveService.setImageStore(fileName, stringMap, condition.getApplyNo());
                }
            }
        }
        //查客户基础信息
        ApplyCustBaseInfo custBaseInfo = new ApplyCustBaseInfo();
        //主借人
        switch (condition.getCustRole()) {
            case ApplyConstants.PRINCIPAL_BORROWER:
                custBaseInfo = this.getCustBaseInfo(condition.getApplyNo(), ApplyConstants.PRINCIPAL_BORROWER);
                break;
            case ApplyConstants.COMMON_BORROWER:
                custBaseInfo = this.getCustBaseInfo(condition.getApplyNo(), ApplyConstants.COMMON_BORROWER);
                break;
            case ApplyConstants.GUARANTOR:
                custBaseInfo = this.getCustBaseInfo(condition.getApplyNo(), ApplyConstants.GUARANTOR);
                break;
            default:
                return null;
        }
        String flag = condition.getCustRole();
        //回显客户信息电子签约附件md5值及类型
        fileId = this.preApproveService.getFileId(null, condition.getApplyNo());
        list.add(fileId);
        if (ObjectUtil.isNotNull(custBaseInfo)) {
            custBaseInfo.setTelPhone(condition.getTelPhone());
            custBaseInfo.setCertNo(condition.getCertNo());
            custBaseInfo.setCertEndDate(condition.getCertEndDate());
            custBaseInfo.setIsLongTerm(condition.getIsLongTerm());
            custBaseInfo.setCustName(condition.getCustName());
            this.updateById(custBaseInfo);
            Map qrCode = this.preApproveService.getQrCode(custBaseInfo.getId(), condition.getApplyNo(), flag);
            list.add(qrCode);
        } else {
            ApplyCustBaseInfo applyCustBaseInfo = new ApplyCustBaseInfo();
            applyCustBaseInfo.setCustRole(condition.getCustRole());
            applyCustBaseInfo.setApplyNo(condition.getApplyNo());
            applyCustBaseInfo.setTelPhone(condition.getTelPhone());
            applyCustBaseInfo.setCertNo(condition.getCertNo());
            applyCustBaseInfo.setCertEndDate(condition.getCertEndDate());
            applyCustBaseInfo.setIsLongTerm(condition.getIsLongTerm());
            applyCustBaseInfo.setCustName(condition.getCustName());
            this.save(applyCustBaseInfo);
            Map qrCode = this.preApproveService.getQrCode(applyCustBaseInfo.getId(), condition.getApplyNo(), flag);
            list.add(qrCode);
        }
        return list;
    }

    /**
     * 删除客户信息，地址信息，联系人信息
     */
    @Override
    public boolean deleteCustomerInfo(CustInfoCondition condition) {
        Long id = condition.getId();
        //删除客户主表信息
        ApplyCustBaseInfo applyCustBaseInfo = this.getOne(Wrappers.<ApplyCustBaseInfo>query().lambda().eq(ApplyCustBaseInfo::getId, id));
        this.removeById(applyCustBaseInfo);
        //删除客户明细
        List<ApplyCustPersonalDetail> personalDetailList = applyCustPersonalService.list(Wrappers.<ApplyCustPersonalDetail>query().lambda().eq(ApplyCustPersonalDetail::getCustId, id));
        if (CollectionUtil.isNotEmpty(personalDetailList)) {
            personalDetailList.forEach(applyCustPersonalService::removeById);
        }
        //删除客户地址
        List<ApplyCustAddressDetails> custAddressDetailsList = applyCustAddressService.list(Wrappers.<ApplyCustAddressDetails>query().lambda().eq(ApplyCustAddressDetails::getCustId, id));
        if (CollectionUtil.isNotEmpty(custAddressDetailsList)) {
            custAddressDetailsList.forEach(applyCustPersonalService::removeById);
        }
        if (ApplyConstants.PRINCIPAL_BORROWER.equals(condition.getCustRole())) {
            //删除客户联系人
            List<ApplyCustContacts> applyCustContactsList = applyCustContactsService.list(Wrappers.<ApplyCustContacts>query().lambda()
                    .eq(ApplyCustContacts::getApplyNo, applyCustBaseInfo.getApplyNo()));
            if (CollectionUtil.isNotEmpty(applyCustContactsList)) {
                applyCustContactsList.forEach(applyCustContactsService::removeById);
            }
        }
        return true;
    }
}
